﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Actya.Core.SiteStructure
{
	[JsonObject(IsReference = true)] 
	public class SitemapNode
	{
		private int _level;

		public string Id { get; set; }
		public string Title { get; set; }
		public string Url { get; set; }
		public string PageId { get; set; }
		public SitemapNode Parent { get; set; }
		public List<SitemapNode> SitemapNodes { get; private set; }
		public bool ShowInNavigation { get; set; }
		public bool ShowInSitemap { get; set; }
		public bool IsHomePage { get; set; }
		public bool IsPrimaryPageReference { get; set; }

		[JsonIgnore]
		public int Level
		{
			get
			{
				if (_level == -1)
				{
					_level = CalculateLevel();
				}
				return _level;
			}
		}

		[JsonIgnore]
		public SitemapNode[] Trail
		{
			get
			{
				var trail = new List<SitemapNode>();
				var node = this;
				while (node != null)
				{
					trail.Add(node);
					node = node.Parent;
				}
				return trail.ToArray();
			}
		}

		public SitemapNode()
		{
			this.Id = Guid.NewGuid().ToString();
			this._level = -1;
			this.SitemapNodes = new List<SitemapNode>();
			this.ShowInNavigation = true;
			this.ShowInSitemap = true;
			this.IsPrimaryPageReference = true;
		}

		public void SetParent(Site site, SitemapNode newParentNode)
		{
			if (newParentNode != this.Parent)
			{
				if (this.Parent != null)
				{
					this.Parent.SitemapNodes.Remove(this);
				}
				else
				{
					site.SitemapNodes.Remove(this);
				}
				if (newParentNode != null)
				{
					newParentNode.SitemapNodes.Add(this);
				}
				else
				{
					site.SitemapNodes.Add(this);
				}
				this.Parent = newParentNode;
			}
			else if (newParentNode == null && ! site.SitemapNodes.Contains(this))
			{
				site.SitemapNodes.Add(this);
			}
		}

		private int CalculateLevel()
		{
			int level = 0;
			var node = this;
			while (node.Parent != null)
			{
				level++;
				node = node.Parent;
			}
			return level;
		}
	}

	public enum SitemapNodeType
	{
		Page,
		Link,
		Folder
	}
}
